package com.cskaoyan.javase.oop2._0encapsulate._0introduction;

/**
 * 封装的基本理解
 * 封装的思想：
 * 封装（encapsulate）是指将数据及相关操作绑定在一起的一种编程机制，使其构成一个不可分割的独立实体。在Java中，类就是这样一种结构。当然，数据被保护在类的内部，是为了尽可能地隐藏内部的细节，只保留一些对外"接口"使之与外部发生联系。
 *
 * 之所以要封装，是为了将代码的使用者和实现者分开。使用者能够完全得到自己想要的功能，又不需要思考过多细节；实现者可以隐藏功能实现的细节，方便灵活进行修改而不影响使用者使用。
 *
 * 封装的语法实现具体来说就是class,还有包括类中结构定义时的访问权限控制,也是一种封装
 *
 * 在实际开发中,绝大多数情况下,类中的属性(成员变量)都应该私有化,避免被外界直接访问
 * 实际上在定义一个类时,直接"无脑"将类中成员变量私有化,一般是不会有问题.
 *
 * 这种写法,主要的目的是为了能够更安全的访问类中的成员变量
 *      1.如果不希望外界直接访问,那就直接私有化
 *      2.如果希望外界能够访问,那么私有化可以避免"对象名."的形式访问
 *          从而提供访问的方法
 *          访问的方法就可以控制成员变量的访问
 *
 * Getter/Setter方法
 * 类中私有化成员变量后,提供Getter方法用于变量的访问
 * 类中私有化成员变量后,提供Setter方法用于变量的赋值
 * Getter/Setter方法有固定/标准的格式,比如:
 * private int age;
 * public int getAge() {
 *     return age;
 * }
 * public void setAge(int age){
 *     this.age = age;
 * }
 *
 * 总之，Getter/Setter方法使成员变量的读、写分离了，从原先的不可控变成了可控。
 * 在实际开发中，一个类的多数成员变量都是私有的
 * 有必要时提供方法访问，无必要的则无需提供。
 *
 *
 * @since 14:20
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        Student s = new Student("张三", 18);
        System.out.println(s.name);
        s.name = "李四";

        System.out.println(s.getAge());
        s.setAge(28);
        System.out.println(s.getAge());

        s.setAge(280);
        System.out.println(s.getAge());

    }
}

class Student {
    String name;
    private int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // 使用Getter/Setter方法后 成员变量的访问就变得可控了
    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        // 年龄应该在1到151
        if (age < 1 || age > 151) {
            System.out.println("非法的年龄!");
            return;
        }
        this.age = age;
    }
}